package org.csu.measure.service;

import org.csu.measure.domain.CKMetrics;
import org.csu.measure.domain.Class;
import org.csu.measure.domain.LKMetrics;
import org.csu.measure.domain.Operation;

import java.util.List;

/**
 * LK
 */
public class LKService {

    private LKMetrics lk;
    private Class targetClass;
    private List<Class> lists;

    public LKService() {
        super();
        lk = new LKMetrics();
    }

    public LKService(Class targetClass, List<Class> lists) {
        super();
        lk = new LKMetrics();
        this.targetClass = targetClass;
        this.lists = lists;
    }

    /** number of operation     属性总数量*/
    private double getAttribute() {
        return targetClass.getAttributes().size();
    }

    /** number of attribute     方法总数量*/
    private double getOperation() {
        return targetClass.getOperations().size();
    }

    /** class size    类规模*/
    private double getCS() {

        return getAttribute() + getOperation();
    }

    /** number of overridden    方法重写数*/
    private double getNOO() {
        Class father = targetClass.getFather();
        int NOO = 0;
        if (father == null) {
            return NOO;
        } else {
            List<Operation> fatherOperation = father.getOperations();
            List<Operation> childOperation = targetClass.getOperations();
            for (int i = 0; i < childOperation.size(); i++) {
                for (int j = 0; j < fatherOperation.size(); j++) {
                    if (childOperation.get(i).getName()
                            .equals(fatherOperation.get(j).getName())) {
                        NOO++;
                    }
                }
            }
        }

        return NOO;
    }

    /** number of add           增加方法数量*/
    private double getNOA() {
        double NOA = 0;
        Class father = targetClass.getFather();

        if(father == null){
            NOA = targetClass.getOperations().size();
        } else{
            NOA = targetClass.getOperations().size() - getNOO();
        }
        return NOA;
    }


    /** specialization index    特征化指数*/
    private double getSI() {
        CKService ckService = new CKService(targetClass, lists);
        CKMetrics ck = ckService.getCk(targetClass);
        double DIT = ck.getDIT();
        double NOO = getNOO();
        double totalMethod = getNOA();
        Class father = targetClass.getFather();
        if(father != null){
            totalMethod += father.getOperations().size();
        }
        double SI = (NOO * DIT) / totalMethod;
        return SI;
    }

    public LKMetrics getLk(Class targetClass) {
        lk.setName(targetClass.getName());
        lk.setOperation(getOperation());
        lk.setAttribute(getAttribute());
        lk.setCS(getCS());
        lk.setNOA(getNOA());
        lk.setNOO(getNOO());
        lk.setSI(getSI());
        return lk;
    }
}
